<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

  <div id="a">
    <span>1</span>
    <p>2</p>
    <a>3</a>
    <div>4</div>
  </div>
  <script>

// Dom 的 collection 是一个 living collection：移动某个 dom 节点到 另外一个地方，会先从原来的 dom 上删除然后在移动到另外一个地方
    // one 20
    // let element = document.getElementById('a')
    // function reverseChildren (element) {
    //   let children = Array.prototype.slice.call(element.childNodes)
    //   for(let child of children) {
    //     element.removeChild(child)
    //   }
    //   element.innerHTML = ''
    //   children.reverse()
    //   for (let child of children) {
    //     element.appendChild(child)
    //   }
    // }
    // reverseChildren(element)
  </script>
  <script>
    // two 50
    // let element = document.getElementById("a")
    // function reverseChildren(element) {
    //   var l = element.childNodes.length
    //   while (l -- > 0) {
    //     element.appendChild(element.childNodes[l])
    //   }
    // }
    // reverseChildren(element)
  </script>
  <script>
    // three 100
    let element = document.getElementById('a')
    function reverseChildren(element) {
      let range = new Range()
      range.selectNodeContents(element)
      let fragment = range.extractContents() //会创建一个 fragment
      // fragment 已经是离开了 document 
      // 对 fragment 操作是对真实的 Dom 树没有任何影响，完全是一种自行计算的过程，不需要发生重排的性能是比较高的 
      // 很多框架都会用到 fragment 和 range 
      let l = fragment.childNodes.length
      while (l-- > 0) {
        fragment.appendChild(fragment.childNodes[l])
      }
      element.appendChild(fragment)
    }
    reverseChildren(element)
  </script>
  <script>
    /*
    创建方法
    1.
    var range= new Range();
    range.setStart(elemnet,9);
    range.setEnd(element,4);
    2.
    var range = document.getSelection().getRangeAt(0);

    range API: 
    range.setStartBefore
    range.setEndBefore
    range.setStartAfter
    range.setEndAfter
    range.selectNode
    range.selectNodeContents
    */
  </script>
</body>
</html>
